package com.boboPlanet.dict.utils;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.boboPlanet.comm.exception.BusinessException;
import com.boboPlanet.dict.entity.dto.GenerateSqlDTO;
import com.boboPlanet.dict.enums.SqlOpeTypeEnum;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description: TODO
 * @Author: mis_wu
 * @Date: 2023/7/25
 * @Company SQL
 **/
public final class GenerateSqlUtil {

    /**
     * 字段分割符
     */
    private static final String FIELD_SPLIT = ",";
    /**
     * 连接符
     */
    private static final String CONNECT_SYMBOL = ".";
    /**
     * 左括号
     */
    private static final String left_bracket_symbol = "(";
    /**
     * 右括号
     */
    private static final String right_bracket_symbol = ")";
    /**
     * 单引号
     */
    private static final String single_mark = "'";

    /**
     * CRUD枚举
     */
    private static class TypeEnum{
        private static final String insert = "insert into ";
        private static final String value = " values ";
    }

    /**
     * 生成一条 insert SQL
     * @param sqlDTO GenerateSqlDTO
     * @return SQL
     */
    public static String buildSaveSqlOne(GenerateSqlDTO sqlDTO){
        assertInsertSql(sqlDTO);
        StringBuilder keysStr = new StringBuilder();
        StringBuilder valStr = new StringBuilder();
        for (String field : sqlDTO.getValueMappings().keySet()) {
            keysStr.append(field).append(FIELD_SPLIT);
            Object val = sqlDTO.getValueMappings().get(field);
            valStr.append(single_mark).append(val).append(single_mark).append(FIELD_SPLIT);
        }
        if (keysStr.length() > 0 && valStr.length() > 0){
            keysStr = new StringBuilder(keysStr.substring(0, keysStr.lastIndexOf(FIELD_SPLIT)));
            valStr = new StringBuilder(valStr.substring(0, valStr.lastIndexOf(FIELD_SPLIT)));
        }
        //插入语句
        return TypeEnum.insert + sqlDTO.getScheme() + CONNECT_SYMBOL + sqlDTO.getTableName() + left_bracket_symbol + keysStr + right_bracket_symbol +
                TypeEnum.value + left_bracket_symbol + valStr + right_bracket_symbol;
    }

    /**
     * 通过上传文件构建 SQL
     * @param file MultipartFile
     * @return String
     */
    public static String buildSaveSqlOne(MultipartFile file,GenerateSqlDTO sqlDTO) throws IOException {
        if (file == null){
            throw BusinessException.build("SQL生成失败,上传字段文件不能为空");
        }
        assertInsertSql(sqlDTO);
        Map<String,Object> valueMappings = new HashMap<>(16);
        //EasyExcel.read(file.getInputStream(), GenerateSqlDTO.class,new SqlEasyExcelListener<GenerateSqlDTO>().sheet().doRead();
        EasyExcel.read(file.getInputStream(), GenerateSqlDTO.class, new PageReadListener<GenerateSqlDTO>(dataList ->{
            for (GenerateSqlDTO sqlData : dataList) {
                valueMappings.put(sqlData.getExcelFields(),sqlData.getExcelValues());
            }
        })).sheet().doRead();
        sqlDTO.setValueMappings(valueMappings);
        //生成SQL
        return buildSaveSqlOne(sqlDTO);

    }


    public static String buildSelectSqlOne(GenerateSqlDTO sqlDTO){
        return "";
    }

    public static List<String> buildSelectSqlBatch(GenerateSqlDTO sqlDTO){
        return null;
    }


    public static void assertInsertSql(GenerateSqlDTO sqlDTO){
        if (sqlDTO == null || sqlDTO.getValueMappings().isEmpty()){
            throw BusinessException.build("构建SQL失败,insert所必须的参数为空");
        }
        if (!SqlOpeTypeEnum.save.name().equals(sqlDTO.getOpeType())){
            throw BusinessException.build("SQL生成失败,不支持的操作类型");
        }
        if (StringUtils.isBlank(sqlDTO.getScheme())){
            throw BusinessException.build("构建SQL失败,脚本库名不能为空");
        }
        if (StringUtils.isBlank(sqlDTO.getTableName())){
            throw BusinessException.build("构建SQL失败,脚本表名不能为空");
        }
    }

}
